/*
 * @(#)UserDao.java
 * 2011-5-9 下午09:07:30
 *
 * Copyright (c) 2018-2028, HangZhou QiYun InfoTech Co.,Ltd. .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.qyxx.platform.sysmng.accountmng.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.stereotype.Component;

import com.qyxx.platform.common.orm.hibernate.HibernateDao;
import com.qyxx.platform.sysmng.accountmng.entity.User;
import com.qyxx.platform.sysmng.utils.Constants;

/**
 *  用户对象的泛型DAO类
 *  
 *  @author gxj
 *  @version 1.0
 *  @since 1.6 2011-5-9 下午09:07:30
 */
@Component
public class UserDao extends HibernateDao<User, Long> {
	
	private static final String SQL_FIND_SEE_USER = 
		    "SELECT m.*, n.VISIBLE_ATTR FROM ("
			+ "SELECT e.RESOURCE_SIGN,a.USER_ID,a.ROLE_ID FROM SYS_ROLE_SEE_USER a, SYS_RESOURCE_TO_ROLE d, SYS_RESOURCE e"
			+ " WHERE a.ROLE_ID = d.ROLE_ID AND d.RESOURCE_ID = e.ID" 
			+ " AND e.RESOURCE_TYPE = '3' AND e.RESOURCE_STATUS = '1'" 
			+ " AND e.RESOURCE_URL like 'selUserVisible%'"
			+ " and a.ROLE_ID IN ("
			+ " SELECT b.ROLE_ID FROM SYS_USER_TO_ROLE b, SYS_ROLE c" 
			+ " WHERE c.ID = b.ROLE_ID AND c.ROLE_STATUS = '1' AND b.USER_ID = ?)"
			+ " ) m LEFT JOIN SYS_ROLE n ON m.ROLE_ID = n.ID ";
	
	private static final String HQL_CHECK_UNIQUE = "select a from User a where a.employeeId = ?";
	
	private static final String HQL_CHECK_UNIQUE_WITH_ID = "select a from User a where a.employeeId = ? and a.id <> ?";
	
	//查找字段条件权限
	private static final String SQL_FIND_FIELD_COND = 
		"SELECT DISTINCT e.RESOURCE_SIGN, c.VISIBLE_ATTR "
		+ " FROM SYS_ROLE c, SYS_RESOURCE_TO_ROLE d, SYS_RESOURCE e, SYS_USER_TO_ROLE b "
		+ " WHERE c.ID = d.ROLE_ID AND b.ROLE_ID = c.ID "
		+ " AND d.RESOURCE_ID = e.ID AND c.ROLE_STATUS = '1' "
		+ " AND e.RESOURCE_TYPE = '3' AND e.RESOURCE_STATUS = '1' "
		+ " AND e.RESOURCE_URL like 'fieldCondVisible%' "
		+ " AND b.USER_ID = ?";
	
	private static final String HQL_VALID_USER_COUNT = "from User a where a.status = ?";
	
	/**
	 * 根据用户查询用户角色可见用户ID列表
	 * 封装成每个模块可见用户ID
	 * 
	 * @param userId
	 * @return
	 */
	public Map<String, Map<String,List<Long>>> findSeeUserByUserId(Long userId) {
		SQLQuery sq = getSession().createSQLQuery(SQL_FIND_SEE_USER);
		sq.addScalar("RESOURCE_SIGN", StandardBasicTypes.STRING).addScalar("USER_ID", StandardBasicTypes.LONG).addScalar("VISIBLE_ATTR", StandardBasicTypes.STRING);
		sq.setLong(0, userId);
		List<Object[]> list = sq.list();
		Map<String, Map<String,List<Long>>> map = new HashMap<String, Map<String,List<Long>>>();
		if(null!=list && !list.isEmpty()) {
			for(Object[] o : list) {
				String resKey = (String)o[0];
				Long seeUserId = (Long)o[1];
				String visibleAttr = (String)o[2];
				if(!map.containsKey(resKey)) {
					map.put(resKey, new HashMap<String,List<Long>>());
				}
				Map<String,List<Long>> tmpMap = map.get(resKey);
				if(!tmpMap.containsKey(visibleAttr)) {
					tmpMap.put(visibleAttr, new ArrayList<Long>());
				}
				tmpMap.get(visibleAttr).add(seeUserId);
			}
		}
		return map;
	}
	
	/**
	 * 根据用户查询用权限控制字段
	 * 
	 * @param userId
	 * @return
	 */
	public Map<String, List<String>> findFieldCondByUserId(Long userId) {
		SQLQuery sq = getSession().createSQLQuery(SQL_FIND_FIELD_COND);
		sq.addScalar("RESOURCE_SIGN", StandardBasicTypes.STRING).addScalar("VISIBLE_ATTR", StandardBasicTypes.STRING);
		sq.setLong(0, userId);
		List<Object[]> list = sq.list();
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		if(null!=list && !list.isEmpty()) {
			for(Object[] o : list) {
				String resKey = (String)o[0];
				String visibleAttr = (String)o[1];
				if(!map.containsKey(resKey)) {
					map.put(resKey, new ArrayList<String>());
				}
				map.get(resKey).add(visibleAttr);
			}
		}
		return map;
	}
	
	/**
	 * 检查是否重复，唯一则返回true
	 * 
	 * @param code
	 * @param id
	 * @return
	 */
	public Boolean checkUnique(String code, Long id) {
		Long count = null;
		if(id != null) {
			count = countHqlResult(HQL_CHECK_UNIQUE_WITH_ID, code, id);
		} else {
			count = countHqlResult(HQL_CHECK_UNIQUE, code);
		}
		return count == 0;
	}
	
	/**
	 * 查询同类型最大编号值
	 * 
	 * @param entityName
	 * @param key
	 * @param prefixVal
	 * @return
	 */
	public String getMaxAutoIdNo(String entityName, String key, String prefixVal) {
		String hql = "select " + key + " from " + entityName + " where " + key + " like ? order by " + key + " desc";
		Query ql = this.createQuery(hql, prefixVal+"%");
		ql.setFirstResult(0);
		ql.setMaxResults(1);
		Object obj = ql.uniqueResult();
		return (String)obj;
	}
	
	/**
	 * 根据用户ID获取用户姓名
	 * 
	 * @param id
	 * @return
	 */
	public String getUserNameById(Long id) {
		if(id == null) {return null;}
		User user = this.get(id);
		if(user != null) {
			return user.getNickname();
		}
		return null;
	}
	
	/**
	 * 根据登录名获取用户姓名
	 * 
	 * @param loginName
	 * @return
	 */
	public String getUserNameByLoginName(String loginName) {
		if(StringUtils.isNotBlank(loginName)) {
			User user = this.findUniqueBy("loginName", loginName);
			if(user != null) {
				return user.getRealName() + "-" + user.getNickname();
			}
		}
		return null;
	}
	
	/**
	 * 获取系统启用用户数量
	 * 
	 * @return
	 */
	public Long getValidUserCount() {
		return countHqlResult(HQL_VALID_USER_COUNT, Constants.ENABLED);
	}
}
